package engine


type ConcurrentEngine struct {
	Scheduler 			Scheduler
	WorkerCount 	int
	ItemChan 			chan Item
}

type Scheduler interface {
	ReadyNotifier
	Submit(Request)
	WorkerChan() 	chan Request
	Run()
}

type ReadyNotifier interface {
	WorkerReady(chan Request)
}

func (e *ConcurrentEngine) Run(seeds ...Request){

	e.Scheduler.Run()
	out := make(chan ParserResult)

	for  i := 0; i < e.WorkerCount; i++ {
		createWorker(e.Scheduler.WorkerChan(),out,e.Scheduler)
	}

	for _, r := range seeds {
		e.Scheduler.Submit(r)
	}

	// 接收 out
	for {
		result := <- out
		for _, item := range result.Items {
			go func() {e.ItemChan <- item}()
		}
		for _, request := range result.Requests {
			e.Scheduler.Submit(request)
		}
	}
}

func createWorker(in chan Request,out chan ParserResult,ready ReadyNotifier){
	go func() {
			for {
				// 告诉scheduler可以开始了
				ready.WorkerReady(in)
				request := <- in
				result, err := worker(request)
				if err != nil {
					continue
				}
				out <- result
			}
	}()
}

